//网络请求封装
import 'package:dio/dio.dart';
import 'package:shenling_flutter/utils/auth.dart';
import 'package:shenling_flutter/utils/event_bus.dart';

class Http {
  final _dio = Dio();

  //设置基地址
  Http() {
    _dio.options.baseUrl = 'https://slwl-api.itheima.net';
    _dio.options.connectTimeout = const Duration(seconds: 5);
    _dio.options.receiveTimeout = const Duration(seconds: 5);
    _dio.options.headers = {'Content-Type': 'application/json'};
    _addInterceptors();
  }

  //封装请求工具
  Future<dynamic> request(
    String method,
    String path,
    dynamic data,
    Map<String, dynamic>? queryParameters,
  ) async {
    try {
      Response response = await _dio.request(
        path,
        data: data,
        queryParameters: queryParameters,
        options: Options(method: method),
      );
      return handleResponse(response);
    } on DioException catch (e) {
      return handleError(e);
    }
  }

  //拦截器
  void _addInterceptors() {
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) async {
        // 请求拦截器：添加公共请求参数、token 等
        // 1.获取token
        final token = Auth().getToken() ?? '';
        if (token.isNotEmpty) {
          // 2.添加token
          options.headers['Authorization'] = token;
        }

        return handler.next(options);
      },
      onResponse: (response, handler) {
        // 响应拦截器：统一处理成功响应
        return handler.next(response);
      },
      onError: (DioException error, handler) {
        // 响应拦截器：统一处理错误响应
        return handler.next(error);
      },
    ));
  }

//响应失败处理
  dynamic handleResponse(Response response) {
    if (response.statusCode! >= 200 && response.statusCode! < 300) {
      return response.data;
    } else {
      throw Exception('请求失败，状态码：${response.statusCode}');
    }
  }

  //错误处理
  dynamic handleError(error) {
    if (error is DioException) {
      if (error.type == DioExceptionType.connectionTimeout ||
          error.type == DioExceptionType.receiveTimeout) {
        throw Exception('网络连接超时');
      } else if (error.type == DioExceptionType.badResponse) {
        //token失效处理
        if (error.response?.statusCode == 401) {
          // 401错误处理
          // 1.清除token
          Auth().removeToken();
          //发送指令
          eventBus.fire(LogoutEvent());
        } else {
          throw Exception('响应错误,状态码: ${error.response?.statusCode}');
        }
      } else {
        throw Exception('网络请求错误:$error');
      }
    } else {
      throw Exception('未知错误：$error');
    }
  }
}

final http = Http();
